//
//  YXHTTPManager.m
//  YXEDU
//
//  Created by shiji on 2018/3/16.
//  Copyright © 2018年 shiji. All rights reserved.
//

#import "BSHTTPManager.h"
#import "AFNetworking.h"

typedef void (^AFURLSessionDownloadTaskDidResumeBlock)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t fileOffset, int64_t expectedTotalBytes);
typedef void (^AFURLSessionDownloadTaskDidFinishDownloadingBlock)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location);

typedef void (^AFURLSessionDownloadTaskDidWriteDataBlock)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite);

@interface BSHTTPManager () <NSURLSessionDownloadDelegate>

@property (readwrite, nonatomic, copy) AFURLSessionDownloadTaskDidWriteDataBlock downloadTaskDidWriteData;

@property (readwrite, nonatomic, copy) AFURLSessionDownloadTaskDidFinishDownloadingBlock downloadFinishBlock;

@end

@implementation BSHTTPManager

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.timeoutInterval = 60;
        self.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
        self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", nil];
    }
    return self;
}

+ (instancetype) shared {
    static BSHTTPManager *shared = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        shared = [BSHTTPManager new];
    });
    return shared;
}

// POST
- (void)POST:(NSString *)URLString headerParams:(id)headerParams parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *, id))success failure:(void (^)(NSURLSessionDataTask *, NSError *))failure {
    //
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.requestSerializer= [AFHTTPRequestSerializer serializer];
    manager.responseSerializer = [AFJSONResponseSerializer serializer];
    
    manager.responseSerializer.acceptableContentTypes = self.acceptableContentTypes;
    manager.requestSerializer.timeoutInterval = self.timeoutInterval;
    manager.requestSerializer.cachePolicy = self.cachePolicy;
    
    if (headerParams) {
        NSMutableDictionary *headerDic = headerParams;
        [headerDic enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
            [manager.requestSerializer setValue:obj forHTTPHeaderField:key];
        }];
    } else if (self.headParams.count) {
        if (self.headParams) {
            NSMutableDictionary *headerDic = self.headParams;
            [headerDic enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
                [manager.requestSerializer setValue:obj forHTTPHeaderField:key];
            }];
        }
    }
    [manager POST:URLString parameters:parameters progress:^(NSProgress * _Nonnull _uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull _task, id  _Nullable _responseObject) {
        success(_task, _responseObject);
    } failure:^(NSURLSessionDataTask * _Nullable _task, NSError * _Nonnull _error) {
        failure(_task, _error);
    }];
}

- (void)POST:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *, id))success failure:(void (^)(NSURLSessionDataTask *, NSError *))failure {
    [self POST:URLString headerParams:nil parameters:parameters success:^(NSURLSessionDataTask * _Nonnull _task, id  _Nullable _responseObject) {
        success(_task, _responseObject);
    } failure:^(NSURLSessionDataTask * _Nullable _task, NSError * _Nonnull _error) {
        failure(_task, _error);
    }];
}

- (void)POST:(NSString *)URLString success:(void (^)(NSURLSessionDataTask *, id))success failure:(void (^)(NSURLSessionDataTask *, NSError *))failure {
    [self POST:URLString parameters:nil success:^(NSURLSessionDataTask * _Nonnull _task, id  _Nullable _responseObject) {
        success(_task, _responseObject);
    } failure:^(NSURLSessionDataTask * _Nullable _task, NSError * _Nonnull _error) {
        failure(_task, _error);
    }];
}

// GET
- (void)GET:(NSString *)URLString headerParams:(id)headerParams parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *, id))success failure:(void (^)(NSURLSessionDataTask *, NSError *))failure  {
    //
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    manager.responseSerializer = [AFJSONResponseSerializer serializer];
    
    manager.responseSerializer.acceptableContentTypes = self.acceptableContentTypes;
    manager.requestSerializer.timeoutInterval = self.timeoutInterval;
    manager.requestSerializer.cachePolicy = self.cachePolicy;
    
    if (headerParams) {
        NSMutableDictionary *headerDic = headerParams;
        [headerDic enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
            [manager.requestSerializer setValue:obj forHTTPHeaderField:key];
        }];
    } else if (self.headParams.count) {
        if (self.headParams) {
            NSMutableDictionary *headerDic = self.headParams;
            [headerDic enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
                [manager.requestSerializer setValue:obj forHTTPHeaderField:key];
            }];
        }
    }
    
    [manager GET:URLString parameters:parameters progress:^(NSProgress * _Nonnull downloadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull _task, id  _Nullable _responseObject) {
        success(_task, _responseObject);
    } failure:^(NSURLSessionDataTask * _Nullable _task, NSError * _Nonnull _error) {
        failure(_task, _error);
    }];
}

- (void)GET:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *, id))success failure:(void (^)(NSURLSessionDataTask *, NSError *))failure  {
    [self GET:URLString headerParams:nil parameters:parameters success:^(NSURLSessionDataTask * _Nonnull _task, id  _Nullable _responseObject) {
        success(_task, _responseObject);
    } failure:^(NSURLSessionDataTask * _Nullable _task, NSError * _Nonnull _error) {
        failure(_task, _error);
    }];
}

- (void)GET:(NSString *)URLString success:(void (^)(NSURLSessionDataTask *, id))success failure:(void (^)(NSURLSessionDataTask *, NSError *))failure  {
    [self GET:URLString parameters:nil success:^(NSURLSessionDataTask * _Nonnull _task, id  _Nullable _responseObject) {
        success(_task, _responseObject);
    } failure:^(NSURLSessionDataTask * _Nullable _task, NSError * _Nonnull _error) {
        failure(_task, _error);
    }];
}


// DOWNLOAD
- (void)DOWNLOAD:(NSString *)URLString fileLength:(NSInteger)length progress:(void (^)(NSProgress *downloadProgress))downloadProgressBlock destination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destinationBlock completion:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionBlock {
    
    self.downloadFinishBlock = ^ void (NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location){
        NSError * fileManagerError = nil;
        NSURL *downloadFileURL = destinationBlock(location, downloadTask.response);
        [[NSFileManager defaultManager] moveItemAtURL:location toURL:downloadFileURL error:&fileManagerError];
        completionBlock(downloadTask.response, location, fileManagerError);
    };
    self.downloadTaskDidWriteData = ^ void (NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) {
        NSProgress *progerss = [[NSProgress alloc]init];
        progerss.totalUnitCount = totalBytesExpectedToWrite;
        progerss.completedUnitCount = totalBytesWritten;
        downloadProgressBlock(progerss);
    };
    
    //创建传话管理者
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    // 1. 创建会话管理者
    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[NSOperationQueue currentQueue]];
    NSURLSessionDownloadTask *task = [session downloadTaskWithURL:[NSURL URLWithString:URLString]];
    [task resume];
}


- (void)DOWNLOAD:(NSString *)URLString progress:(void (^)(NSProgress *downloadProgress))downloadProgressBlock destination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destinationBlock completion:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionBlock {
    
    [self DOWNLOAD:URLString progress:^(NSProgress *downloadProgress) {
        
    } destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
        return destinationBlock(targetPath, response);
    } completion:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
        completionBlock(response, filePath, error);
    }];
}



#pragma -NSURLSessionDownloadDelegate-
-(void)URLSession:(nonnull NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
    self.downloadTaskDidWriteData(session, downloadTask, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
}

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location {
    self.downloadFinishBlock(session, downloadTask,location);
}

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
 didResumeAtOffset:(int64_t)fileOffset
expectedTotalBytes:(int64_t)expectedTotalBytes {
    
}

@end
